//
// Created by QU on 24-6-19.
//
#include <iostream>
#include <functional>
#include <utility>
#include <memory>
#include <vector>
#include <map>
#include <set>
#include <new>
#include <thread>
#include <algorithm>
#include <array>
#include <string>
#include <deque>

using std::cout, std::cin, std::endl;

// c++11 lambda 类类型  (无名的非联合(union), 非聚合类 类类型) 也称为闭包类型              注意是类类型
// 每个Lambda表达式在编译时生成一个唯一的匿名类，该类重载了operator()以实现Lambda体内的代码。
// 证明: 用类X, 继承一个lambda的返回值.
struct X : decltype([] { std::cout << "666\n"; })
{
};

int main(int argc, char const* argv[])
{
    // [捕获列表] (形参列表) {函数体}
    // & 按引用隐式捕获被使用的自动存储期变量
    // = 按复制隐式捕获被使用的自动存储期变量
    auto p = []
    {
    };

    // operator()() const,   不能修改 num的值.
    auto p1 = [num = 0]
    {
        // num = 10;            // error
    };

    // mutable 关键字的使用：mutable修饰的成员变量允许在const成员函数中修改。
    auto p2 = [num = 0]()mutable
    {
        num = 10;
    };

    // 如果该变量具有const而非volatile的整型或枚举类型，并已经用常量表达式初始化，
    // 或者该变量是constexpr的且没有mutable成员。（这是表示即使不使用=捕获在这里的语境下直接用也没问题）
    // lambda表达式在读取它的值前 不需要先捕获.
    const int N = 10;
    auto p3 = [=]
    {
        int arr[N]{};
    };      // sizeof p3       值为 1

    // c++20  有显式模板形参的 lambda 表达式（必然泛型）
    // https://zh.cppreference.com/w/cpp/language/lambda
    auto p4 = []<typename T>(T n) { std::cout << n << std::endl; };

    cout << sizeof(p) << endl; // 空类 1
    cout << sizeof(p1) << endl; // 4

    p2();
    cout << "p3 size: " << sizeof p3 << endl;
    p4(20);
    p4("aquawius");

    return 0;
}
